package com.societyGames.flashForms
{
import flash.display.Sprite;
import flash.events.Event;

public class DialogManager extends Sprite
{
  public static const instance:DialogManager = new DialogManager();

  private var _dialogs:Vector.<IDialog> = new Vector.<IDialog>();
  private var _curtain:Sprite = new Sprite();

  public function DialogManager()
  {
    this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
    this._curtain.visible = false;
  }

  public function showDialog(dialog:IDialog):void
  {
    this._dialogs.push(dialog);
    dialog.completeEventObject.addEventListener(dialogCompleteHandler);
    recalculateDialogSizeAndPosition();
    this._curtain.visible = true;
    this.addChild(this._curtain); //Move it to the top.
    this.addChild(dialog.displayObject);
  }

  private function recalculateDialogSizeAndPosition():void
  {
    for each(var dialog:IDialog in _dialogs)
    {
      if (dialog.displayObject.width < this._curtain.width)
      {
        dialog.displayObject.x = (this._curtain.width - dialog.displayObject.width) / 2;
      }
      else
      {
        dialog.displayObject.x = 0;
        dialog.displayObject.width = this._curtain.width;
      }
      if (dialog.displayObject.height < this._curtain.height)
      {
        dialog.displayObject.y = (this._curtain.height - dialog.displayObject.height) / 2;
      }
      else
      {
        dialog.displayObject.y = 0;
        dialog.displayObject.height = this._curtain.height;
      }
    }
  }

  public function hideDialog(dialog:IDialog):void
  {
    var index:int = this._dialogs.indexOf(dialog);
    if (index != -1)
    {
      this._dialogs.splice(index, 1); //Remove from vector.
      dialog.completeEventObject.removeEventListener(dialogCompleteHandler); //Unhook
      this.removeChild(dialog.displayObject); //Unhook display
      if (this._dialogs.length == 0) //Hide curtain
      {
        this._curtain.visible = false;
      }
      else
      {
        this.addChild(this._curtain);
        this.addChild(this._dialogs[this._dialogs.length - 1].displayObject);
      }
    }
  }

  private function dialogCompleteHandler(event:Event):void
  {
    hideDialog(IDialog(event.target));
  }

  private function addedToStageHandler(event:Event):void
  {
    this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
    this.addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
    this.stage.addEventListener(Event.RESIZE, stageResizeHandler);
    stageResizeHandler(null);
  }

  private function removedFromStageHandler(event:Event):void
  {
    this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
    this.removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
    this.stage.removeEventListener(Event.RESIZE, stageResizeHandler);
  }

  private function stageResizeHandler(event:Event):void
  {
    this._curtain.graphics.clear();
    this._curtain.graphics.beginFill(0x000000, 0.3);
    this._curtain.graphics.drawRect(0, 0, this.stage.stageWidth, this.stage.stageHeight);

    recalculateDialogSizeAndPosition();
  }
}
}